package cn.big.bigd.biocode.service;


import cn.big.bigd.biocode.dao.UserDAO;
import cn.big.bigd.biocode.model.Role;
import cn.big.bigd.biocode.model.User;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.security.cas.authentication.CasAssertionAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Created by zoud on 2016/9/26.
 **/
@Service
@Order(3)
public class UserService implements AuthenticationUserDetailsService<CasAssertionAuthenticationToken> {
   private static final Logger logger = LoggerFactory.getLogger(UserService.class);
   
    @Autowired
    private UserDAO userDAO;

    @Autowired
    private PasswordEncoder passwordEncoder;

    public User findById(Long id) {
        return userDAO.findOne(id);
    }

  /*  @Override
    public UserDetails loadUserByUsername(String username) throws BadCredentialsException {
        User user = userDAO.findByEmailOrUsername(username, username);
        if (user == null) {
            throw new BadCredentialsException("User is not exist!");
        }
        if(user.getStatus()==0){
            throw new BadCredentialsException("Email: " + username+ " don't active");
        }

        List<SimpleGrantedAuthority> authorities = user.getRoleList().stream().map(role -> new SimpleGrantedAuthority(role.getName())).collect(Collectors.toList());


        // SecurityUser实现UserDetails并将SUser的Email映射为username
        return new org.springframework.security.core.userdetails.User(user.getEmail(), user.getPassword(), authorities);

    }*/


    public String encode(String str) {

        return passwordEncoder.encode(str);
    }

    private User encodePassword(User user) {
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        return user;
    }

    public void createAdminUser(String email, String username, String password) {
        User user = new User();
        user.setEmail(email);
        user.setUsername(username);
        user.setPassword(password);
        user.addRole(Role.ADMIN);
        encodePassword(user);
        userDAO.save(user);
    }

    public void createUser(String email, String username, String password) {
        User user = new User();
        user.setEmail(email);
        user.setUsername(username);
        user.setPassword(password);
        user.addRole(Role.USER);
        encodePassword(user);
        userDAO.save(user);
    }
    public User createUser(String email, String fullname,boolean signUP) {
        User user = new User();
        user.setEmail(email);
        user.setUsername(email);
        user.setFullName(fullname);
        user.setSignedUp(signUP);
        user.setPassword("123456");
        user.addRole(Role.USER);
        encodePassword(user);
        return  userDAO.save(user);
    }



    public Long count() {
        return userDAO.count();
    }

    public User findByEmail(String email) {
        return userDAO.findByEmail(email);
    }

    public void save(User user) {
        userDAO.save(user);
    }


    public void deleteById(Long id) {
        userDAO.delete(id);
    }


    @Override
    public UserDetails loadUserDetails(CasAssertionAuthenticationToken casAssertionAuthenticationToken) throws UsernameNotFoundException {
        String username = casAssertionAuthenticationToken.getPrincipal().toString();
        AttributePrincipal principal = casAssertionAuthenticationToken.getAssertion().getPrincipal();
        Map attributes = principal.getAttributes();

        if (username.isEmpty()) {
            throw new UsernameNotFoundException("username not found");
        } else {
            if (userDAO.existsByEmail(username)) {
                User user = userDAO.findByEmail(username);
                logger.info(user.getRoleList().toString());

                List<SimpleGrantedAuthority> authorities = user.getRoleList().stream().map(role -> new SimpleGrantedAuthority(role.getName())).collect(Collectors.toList());
                return new org.springframework.security.core.userdetails.User(user.getEmail(), user.getPassword(), authorities);
            } else {
                User user = new User();

                user.setEmail(attributes.get("email").toString());

                user.setUsername(username);
                user.setPassword(passwordEncoder.encode("big123!"));
                List<Role> roleList = new ArrayList<>();
                roleList.add(Role.USER);
                user.setRoleList(roleList);
                user = userDAO.save(user);

                logger.info(user.toString());
                List<SimpleGrantedAuthority> authorities = user.getRoleList().stream().map(role -> new SimpleGrantedAuthority(role.getName())).collect(Collectors.toList());
                return new org.springframework.security.core.userdetails.User(user.getEmail(), user.getPassword(), authorities);


            }
        }
    }
}
